package cn.hebutrun.oulabot.common;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.jboss.logging.MDC;

/**
 * 通用返回包装类
 *
 * @param <T> 泛型type，可传入任意类
 * @author zhaolong
 */
@Data
@ApiModel(value = "通用返回类")
public final class ApiResponse<T> {
  /** 新建默认的成功对象和失败对象 */
  private static final ApiResponse<Object> SUCCESS = new ApiResponse<>(0, true, "success", null);

  private static final ApiResponse<Object> ERROR = new ApiResponse<>(1, false, "error", null);

  /** 状态码 0：成功 1：失败 其他状态码均代表失败 */
  @ApiModelProperty(value = "返回响应码，0为成功，其他为失败")
  private int code;

  @ApiModelProperty(value = "返回标志位，true为成功，false为失败")
  private boolean success;

  /** 返回信息 通用返回信息为success或error */
  @ApiModelProperty(value = "返回信息")
  private String msg;

  /** 返回数据 T为模板类 */
  @ApiModelProperty(value = "返回数据")
  private T data;

  /**
   * 构造函数 用于装配对象并返回
   *
   * @param code 响应码
   * @param msg 返回信息
   * @param data 返回数据
   */
  public ApiResponse(int code, boolean success, String msg, T data) {
    this.code = code;
    this.msg = msg;
    this.success = success;
    this.data = data;
  }

  /**
   * 失败返回方法
   *
   * @param code 响应码
   * @param msg 返回信息
   * @param data 返回数据
   * @return 返回对象
   */
  public static <T> ApiResponse<T> error(int code, String msg, T data) {
    return new ApiResponse<>(code, ERROR.isSuccess(), msg, data);
  }

  /**
   * 只返回错误信息，使用默认code和data
   *
   * @param msg 返回信息
   * @return 返回对象
   */
  public static ApiResponse<String> error(String msg) {
    return new ApiResponse<>(
        ERROR.getCode(), ERROR.isSuccess(), msg, "请求id:" + MDC.get(Constants.REQUEST_ID_KEY));
  }

  /**
   * 只返回错误信息和数据，使用默认code
   *
   * @param msg 返回信息
   * @param data 返回数据
   * @return 返回对象
   */
  public static <T> ApiResponse<T> error(String msg, T data) {
    return new ApiResponse<>(ERROR.getCode(), ERROR.isSuccess(), msg, data);
  }

  /**
   * 只返回code和msg
   *
   * @param code 响应码
   * @param msg 返回信息
   * @return 返回对象
   */
  public static ApiResponse<String> error(int code, String msg) {
    return new ApiResponse<>(
        code, ERROR.isSuccess(), msg, "请求id:" + MDC.get(Constants.REQUEST_ID_KEY));
  }

  /**
   * 根据错误枚举返回
   *
   * @param errorEnum 返回错误枚举
   * @return 返回对象
   */
  public static ApiResponse<String> error(ErrorEnum errorEnum) {
    return new ApiResponse<>(
        errorEnum.getCode(),
        ERROR.isSuccess(),
        errorEnum.getMsg(),
        "请求id:" + MDC.get(Constants.REQUEST_ID_KEY));
  }

  /**
   * 只返回数据，使用默认的code和msg
   *
   * @param data 返回数据
   * @return 返回对象
   */
  public static <T> ApiResponse<T> success(T data) {
    return new ApiResponse<>(SUCCESS.getCode(), SUCCESS.isSuccess(), SUCCESS.getMsg(), data);
  }

  /**
   * 成功返回值
   *
   * @return 默认返回
   */
  public static <T> ApiResponse<T> success() {
    return new ApiResponse<>(SUCCESS.getCode(), SUCCESS.isSuccess(), SUCCESS.getMsg(), null);
  }

  public static ApiResponse<String> of(boolean isSucceed, String errorMsg) {
    if (isSucceed) {
      return success();
    }
    return error(errorMsg);
  }

  public static ApiResponse<String> of(boolean isSucceed, ErrorEnum errorEnum) {
    if (isSucceed) {
      return success();
    }
    return error(errorEnum);
  }
}
